package main

import (
	"bytes"
	"fmt"
	"net"
	"sync"
	"time"

	"micro-rulego/internal/biz/channel"
	"micro-rulego/internal/biz/device"
	"micro-rulego/internal/conf"

	"github.com/go-kratos/kratos/v2/log"
)

type DebugCollector struct {
	deviceMngr  device.DeviceManager
	channelMngr channel.ChannelManager
	done        chan bool
	connections map[net.Conn]bool
	interval    time.Duration
	ticker      *time.Ticker
	address     string
	mu          sync.Mutex
	enabled     bool
}

func NewDebugCollector(d *conf.Debug, deviceMngr device.DeviceManager, channelMngr channel.ChannelManager) *DebugCollector {
	enabled := false
	address := "127.0.0.1:23"
	interval := 5 * time.Second
	if d != nil {
		if d.Enabled {
			enabled = d.Enabled
		}
		if d.Address != "" {
			address = d.Address
		}
		if d.Interval.AsDuration() > 0 {
			interval = d.Interval.AsDuration()
		}
	}
	return &DebugCollector{
		deviceMngr:  deviceMngr,
		channelMngr: channelMngr,
		done:        make(chan bool),
		connections: make(map[net.Conn]bool),
		enabled:     enabled,
		address:     address,
		interval:    interval,
	}
}

func (d *DebugCollector) Start() error {
	if !d.enabled {
		log.Info("Debug collector is disabled")
		return nil
	}
	log.Infof("Debug collector is enabled, address: %s", d.address)
	listener, err := net.Listen("tcp", d.address)
	if err != nil {
		return fmt.Errorf("telnet server listen error: %v", err)
	}
	go func() {
		for {
			conn, err := listener.Accept()
			if err != nil {
				continue
			}

			go d.handleTelnetConnection(conn)
		}
	}()

	d.ticker = time.NewTicker(d.interval)
	go func() {
		for {
			select {
			case <-d.ticker.C:
				d.collectAndPrintDebugInfo()
			case <-d.done:
				d.ticker.Stop()
				return
			}
		}
	}()

	return nil
}

func (d *DebugCollector) Stop() {
	if d.enabled {
		d.done <- true
	}
}

func (d *DebugCollector) collectAndPrintDebugInfo() {
	var buf bytes.Buffer

	// 清屏并将光标移到开头
	buf.WriteString("\033[2J\033[H")

	// 设备信息部分
	devices, err := d.deviceMngr.DeivceCheck()
	fmt.Fprintln(&buf, "=== 设备信息 ===")
	if err != nil {
		fmt.Fprintf(&buf, "获取设备信息失败: %v\n", err)
	} else if len(devices) == 0 {
		fmt.Fprintln(&buf, "当前无设备")
	} else {
		fmt.Fprintf(&buf, "设备总数: %d\n", len(devices))
		fmt.Fprintln(&buf, "----------------------------------------")
		for deviceID := range devices {
			fmt.Fprintf(&buf, "设备ID: %-4d\n", deviceID)

			connects, err := d.deviceMngr.DeviceConnectCheck(deviceID)
			if err != nil {
				fmt.Fprintf(&buf, "    ├── 获取连接信息失败: %v\n", err)
			} else if len(connects) == 0 {
				fmt.Fprintf(&buf, "    └── 无连接\n")
			} else {
				fmt.Fprintf(&buf, "    ├── 连接数量: %d\n", len(connects))
				i := 0
				for connectID, status := range connects {
					prefix := "    ├──"
					if i == len(connects)-1 {
						prefix = "    └──"
					}
					fmt.Fprintf(&buf, "%s 连接ID: %-4d | 可用状态: %-6v\n",
						prefix, connectID, status.IsAvaliable)
					i++
				}
			}
			fmt.Fprintln(&buf, "----------------------------------------")
		}
	}

	// 通道信息部分
	channels, err := d.channelMngr.ChannelCheck()
	fmt.Fprintln(&buf, "\n=== 通道信息 ===")
	if err != nil {
		fmt.Fprintf(&buf, "获取通道信息失败: %v\n", err)
	} else if len(channels) == 0 {
		fmt.Fprintln(&buf, "当前无通道")
	} else {
		fmt.Fprintf(&buf, "通道总数: %d\n", len(channels))
		fmt.Fprintln(&buf, "----------------------------------------")
		for channelID, channelInfo := range channels {
			fmt.Fprintf(&buf, "通道ID: %-4d | 类型: %s | 状态: %s\n", channelID, channelInfo.Type, channelInfo.Status)
			if len(channelInfo.EntryInfos) == 0 {
				fmt.Fprintf(&buf, "    └── 无通道接口\n")
			} else {
				fmt.Fprintf(&buf, "    ├── 通道接口数量: %d\n", len(channelInfo.EntryInfos))
				i := 0
				for entryID, info := range channelInfo.EntryInfos {
					prefix := "    ├──"
					if i == len(channelInfo.EntryInfos)-1 {
						prefix = "    └──"
					}
					fmt.Fprintf(&buf, "%s 通道接口ID: %-4d | 设备ID: %-4d | 连接ID: %-4d\n",
						prefix, entryID, info[0], info[1])
					i++
				}
			}
			fmt.Fprintln(&buf, "----------------------------------------")
		}
	}

	fmt.Fprintf(&buf, "\n%s\n",
		time.Now().Format("2006-01-02 15:04:05"))

	// 将缓冲的内容写入所有连接
	d.mu.Lock()
	for conn := range d.connections {
		_, err := conn.Write(buf.Bytes())
		if err != nil {
			// 如果写入失败，移除该连接
			delete(d.connections, conn)
			conn.Close()
		}
	}
	d.mu.Unlock()
}

func (d *DebugCollector) AddConnection(conn net.Conn) {
	d.mu.Lock()
	d.connections[conn] = true
	d.mu.Unlock()
}

func (d *DebugCollector) RemoveConnection(conn net.Conn) {
	d.mu.Lock()
	delete(d.connections, conn)
	d.mu.Unlock()
}

func (d *DebugCollector) handleTelnetConnection(conn net.Conn) {
	defer conn.Close()

	d.AddConnection(conn)
	defer d.RemoveConnection(conn)

	// 简单的读取循环，保持连接活跃
	buf := make([]byte, 1024)
	for {
		_, err := conn.Read(buf)
		if err != nil {
			return
		}
	}
}
